namespace GYLite{
    export class WebGLVertext3DObject{
        public vertexIndex:number;
        public indexIndex:number;

        public tpVertexIndex:number;
        public tpIndexIndex:number;

        public vertSize:number;
        public vertByteSize:number;
        public maxQuadsCount:number;
        public maxVertexCount:number;
        public maxIndicesCount:number;
        
        protected _vertices:ArrayBuffer;        
        protected _verticesFloat32View:Float32Array;
        protected _verticesUint32View:Uint32Array;
        public indices:Uint16Array;

        protected _tpVertices:ArrayBuffer;        
        protected _tpVerticesFloat32View:Float32Array;
        protected _tpVerticesUint32View:Uint32Array;
        public tpIndices:Uint16Array;

        public vertextIndex:number;
        public indicesIndex:number;
        public vertices:ArrayBuffer;
        public tpVertices:ArrayBuffer;
        constructor()
        {
            let s= this;
            s.vertexIndex = s.indexIndex = s.tpIndexIndex = s.tpVertexIndex = 0;
            //float(x,y,z,w)-4*4 float(u,v)-4*2 byte(argb)-4*1 float(matrix3D)-16*4 
            //4*4+4*2+4*1+4*16

            s.vertSize = 4+2+1+16;
            s.vertByteSize = s.vertSize * 4;
            s.maxQuadsCount = 2048*32;
            s.maxVertexCount = s.maxQuadsCount * 4;
            s.maxIndicesCount = s.maxQuadsCount * 6;

            s._vertices = new ArrayBuffer(s.maxVertexCount*s.vertByteSize);
            s._verticesFloat32View = new Float32Array(s._vertices);
            s._verticesUint32View = new Uint32Array(s._vertices);
            s.vertices = s._vertices;

            s._tpVertices = new ArrayBuffer(s.maxVertexCount*s.vertByteSize);
            s._tpVerticesFloat32View = new Float32Array(s._tpVertices);
            s._tpVerticesUint32View = new Uint32Array(s._tpVertices);
            s.tpVertices = s._vertices;

            var maxIndicesCount = s.maxIndicesCount;
            s.indices = new Uint16Array(maxIndicesCount);            
            // for (var i = 0, j = 0; i < maxIndicesCount; i += 6, j += 4) {
            //     s.indices[i + 0] = j + 0;
            //     s.indices[i + 1] = j + 1;
            //     s.indices[i + 2] = j + 2;
            //     s.indices[i + 3] = j + 0;
            //     s.indices[i + 4] = j + 2;
            //     s.indices[i + 5] = j + 3;
            // }
            s.tpIndices = new Uint16Array(maxIndicesCount);            
            // for (var i = 0, j = 0; i < maxIndicesCount; i += 6, j += 4) {
            //     s.tpIndices[i + 0] = j + 0;
            //     s.tpIndices[i + 1] = j + 1;
            //     s.tpIndices[i + 2] = j + 2;
            //     s.tpIndices[i + 3] = j + 0;
            //     s.tpIndices[i + 4] = j + 2;
            //     s.tpIndices[i + 5] = j + 3;
            // }
        }
        public reachMaxSize(vertexCount:number=4, indexCount:number=6) {
            let s =this;            
            return s.vertexIndex > s.maxVertexCount - vertexCount || s.indexIndex > s.maxIndicesCount - indexCount;
        }
        public getVertices():ArrayBuffer {
            let s= this;
            var view = (<Float32Array>s.vertices).subarray(0, s.vertexIndex * s.vertSize);
            return view;
        }
        public getIndices():ArrayBuffer {
            return this.indices;
        }
        public cacheArrays(buffer, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, destWidth, destHeight, textureSourceWidth, textureSourceHeight, meshUVs, meshVertices, meshIndices, rotated, color) {
            var alpha = buffer.globalAlpha;
            /*
            * 混入tintcolor => alpha
            */
            alpha = Math.min(alpha, 1.0);
            var globalTintColor;
            var currentTexture = buffer.currentTexture;
            var preMulAlpha;
            var noTransform,x0,y0;
            //GYLite 增加节点颜色功能
            if(color != null)
                globalTintColor = color;
            else
                globalTintColor = buffer.globalTintColor || 0xFFFFFF;
            preMulAlpha = currentTexture && currentTexture[egret.UNPACK_PREMULTIPLY_ALPHA_WEBGL];
            alpha = (preMulAlpha && alpha < 1.0) ? egret.WebGLUtils.premultiplyTint(globalTintColor, alpha) : (globalTintColor + (alpha * 255 << 24));//GYLite
            /*
            临时测试
            */
            //计算出绘制矩阵，之后把矩阵还原回之前的
            let locWorldTransform = buffer.globalMatrix;
            let a = locWorldTransform.a;
            let b = locWorldTransform.b;
            let c = locWorldTransform.c;
            let d = locWorldTransform.d;
            let e = locWorldTransform.e
            let tx = locWorldTransform.tx;
            let ty = locWorldTransform.ty;
            let offsetX = buffer.$offsetX;
            let offsetY = buffer.$offsetY;
            //GYLite 对没变换的矩阵优化计算
            noTransform = a == 1 && d == 1 && b == 0 && c == 0 && e == 0;
            if (offsetX != 0 || offsetY != 0) {                    
                if(noTransform)
                {
                    tx += offsetX;
                    ty += offsetY;
                }
                else
                {
                    tx = offsetX * a + offsetY * c + tx;
                    ty = offsetX * b + offsetY * d + ty;
                }                    
            }
            if (!meshVertices) {
                if (destX != 0 || destY != 0) {
                    if(noTransform)
                    {
                        tx += destX;
                        ty += destY;
                    }
                    else
                    {
                        tx = destX * a + destY * c + tx;
                        ty = destX * b + destY * d + ty;
                    }                        
                }
                var a1 = destWidth / sourceWidth;
                if (a1 != 1) {
                    a = a1 * a;
                    b = a1 * b;
                }
                var d1 = destHeight / sourceHeight;
                if (d1 != 1) {
                    c = d1 * c;
                    d = d1 * d;
                }
            }
            noTransform = a == 1 && d == 1 && b == 0 && c == 0;
            if (meshVertices) {
                if (egret.web.isIOS14Device()) {
                    var vertData = [];
                    // 计算索引位置与赋值
                    var vertices = this.vertices;
                    var verticesUint32View = this._verticesUint32View;
                    var index = this.vertexIndex * this.vertSize;
                    // 缓存顶点数组
                    var i = 0, iD = 0, l = 0;
                    var u = 0, v = 0, x = 0, y = 0;
                    for (i = 0, l = meshUVs.length; i < l; i += 2) {
                        iD = index + i * 5 / 2;
                        x = meshVertices[i];
                        y = meshVertices[i + 1];
                        u = meshUVs[i];
                        v = meshUVs[i + 1];
                        //GYLite 对无变换的矩阵优化
                        if(noTransform)
                        {
                            x0 = x + tx;
                            y0 = y + ty;
                        }
                        else
                        {
                            x0 = a * x + c * y + tx;
                            y0 = b * x + d * y + ty;
                        }
                        if (rotated) {
                            vertData.push([
                                x0,
                                y0,
                                (sourceX + (1.0 - v) * sourceHeight) / textureSourceWidth,
                                (sourceY + u * sourceWidth) / textureSourceHeight,
                            ]);
                        }
                        else {
                            vertData.push([
                                x0,
                                y0,
                                (sourceX + u * sourceWidth) / textureSourceWidth,
                                (sourceY + v * sourceHeight) / textureSourceHeight,
                            ]);
                        }                            
                        verticesUint32View[iD + 4] = alpha;
                    }
                    for (var i_1 = 0; i_1 < meshIndices.length; i_1 += 3) {
                        var data0 = vertData[meshIndices[i_1]];
                        vertices[index++] = data0[0];
                        vertices[index++] = data0[1];
                        vertices[index++] = data0[2];
                        vertices[index++] = data0[3];
                        index++;
                        // verticesUint32View[index++] = alpha;//GYLite 上面已经给alpha赋值了
                        var data1 = vertData[meshIndices[i_1 + 1]];
                        vertices[index++] = data1[0];
                        vertices[index++] = data1[1];
                        vertices[index++] = data1[2];
                        vertices[index++] = data1[3];
                        index++;
                        // verticesUint32View[index++] = alpha;//GYLite 上面已经给alpha赋值了
                        var data2 = vertData[meshIndices[i_1 + 2]];
                        vertices[index++] = data2[0];
                        vertices[index++] = data2[1];
                        vertices[index++] = data2[2];
                        vertices[index++] = data2[3];
                        index++;
                        // verticesUint32View[index++] = alpha;//GYLite 上面已经给alpha赋值了
                        // 填充数据
                        vertices[index++] = data2[0];
                        vertices[index++] = data2[1];
                        vertices[index++] = data2[2];
                        vertices[index++] = data2[3];
                        index++;
                        // verticesUint32View[index++] = alpha;//GYLite 上面已经给alpha赋值了
                    }
                    var meshNum = meshIndices.length / 3;
                    this.vertexIndex += 4 * meshNum;
                    this.indexIndex += 6 * meshNum;
                }
                else {
                    // 计算索引位置与赋值
                    var vertices = this.vertices;
                    var verticesUint32View = this._verticesUint32View;
                    var index = this.vertexIndex * this.vertSize;
                    // 缓存顶点数组
                    var i = 0, iD = 0, l = 0;
                    var u = 0, v = 0, x = 0, y = 0;
                    for (i = 0, l = meshUVs.length; i < l; i += 2) {
                        iD = index + i * 5 / 2;
                        x = meshVertices[i];
                        y = meshVertices[i + 1];
                        u = meshUVs[i];
                        v = meshUVs[i + 1];
                        //GYLite 对无变换的矩阵优化
                        if(noTransform)
                        {
                            x0 = x + tx;
                            y0 = y + ty;
                        }
                        else
                        {
                            x0 = a * x + c * y + tx;
                            y0 = b * x + d * y + ty;
                        }
                        // xy
                        vertices[iD + 0] = x0;
                        vertices[iD + 1] = y0;
                        // uv
                        if (rotated) {
                            vertices[iD + 2] = (sourceX + (1.0 - v) * sourceHeight) / textureSourceWidth;
                            vertices[iD + 3] = (sourceY + u * sourceWidth) / textureSourceHeight;
                        }
                        else {
                            vertices[iD + 2] = (sourceX + u * sourceWidth) / textureSourceWidth;
                            vertices[iD + 3] = (sourceY + v * sourceHeight) / textureSourceHeight;
                        }                            
                        verticesUint32View[iD + 4] = alpha;
                    }
                    // 缓存索引数组
                    // if (this.hasMesh) {
                    //     for (var i_2 = 0, l_1 = meshIndices.length; i_2 < l_1; ++i_2) {
                    //         this.indicesForMesh[this.indexIndex + i_2] = meshIndices[i_2] + this.vertexIndex;
                    //     }
                    // }
                    this.vertexIndex += meshUVs.length / 2;
                    this.indexIndex += meshIndices.length;
                }
            }
            else {
                var width = textureSourceWidth;
                var height = textureSourceHeight;
                var w = sourceWidth;
                var h = sourceHeight;
                sourceX = sourceX / width;
                sourceY = sourceY / height;
                var vertices = this.vertices;
                var verticesUint32View = this._verticesUint32View;
                var index = this.vertexIndex * this.vertSize;
                if (rotated) {
                    var temp = sourceWidth;
                    sourceWidth = sourceHeight / width;
                    sourceHeight = temp / height;
                    // xy
                    vertices[index++] = tx;
                    vertices[index++] = ty;
                    // uv
                    vertices[index++] = sourceWidth + sourceX;
                    vertices[index++] = sourceY;
                    // alpha
                    verticesUint32View[index++] = alpha;
                    // xy                      
                    //GYLite 对无变换的矩阵优化
                    if(noTransform)  
                    {
                        vertices[index++] = w + tx;                                                
                        vertices[index++] = ty; 
                    }
                    else
                    {
                        vertices[index++] = a * w + tx;                                                
                        vertices[index++] = b * w + ty;                        
                    }                        
                    // uv
                    vertices[index++] = sourceWidth + sourceX;
                    vertices[index++] = sourceHeight + sourceY;
                    // alpha
                    verticesUint32View[index++] = alpha;
                    // xy
                    //GYLite 对无变换的矩阵优化
                    if(noTransform)
                    {
                        vertices[index++] = w + tx;
                        vertices[index++] = h + ty;
                    }
                    else
                    {
                        vertices[index++] = a * w + c * h + tx;
                        vertices[index++] = d * h + b * w + ty;
                    }                        
                    // uv
                    vertices[index++] = sourceX;
                    vertices[index++] = sourceHeight + sourceY;
                    // alpha
                    verticesUint32View[index++] = alpha;
                    // xy
                    if(noTransform)
                    {
                        vertices[index++] = tx;
                        vertices[index++] = h + ty;
                    }
                    else
                    {
                        vertices[index++] = c * h + tx;
                        vertices[index++] = d * h + ty;   
                    }                        
                    // uv                        
                    vertices[index++] = sourceX;
                    vertices[index++] = sourceY;
                    // alpha
                    verticesUint32View[index++] = alpha;
                }
                else {
                    sourceWidth = sourceWidth / width;
                    sourceHeight = sourceHeight / height;
                    // xy
                    vertices[index++] = tx;
                    vertices[index++] = ty;
                    // uv
                    vertices[index++] = sourceX;
                    vertices[index++] = sourceY;
                    // alpha
                    verticesUint32View[index++] = alpha;
                    // xy
                    //GYLite 对无变换的矩阵优化
                    if(noTransform)  
                    {
                        vertices[index++] = w + tx;                                                
                        vertices[index++] = ty; 
                    }
                    else
                    {
                        vertices[index++] = a * w + tx;                                                
                        vertices[index++] = b * w + ty;                        
                    }  
                    // uv
                    vertices[index++] = sourceWidth + sourceX;
                    vertices[index++] = sourceY;
                    // alpha
                    verticesUint32View[index++] = alpha;
                    // xy
                    //GYLite 对无变换的矩阵优化
                    if(noTransform)
                    {
                        vertices[index++] = w + tx;
                        vertices[index++] = h + ty;
                    }
                    else
                    {
                        vertices[index++] = a * w + c * h + tx;
                        vertices[index++] = d * h + b * w + ty;
                    } 
                    // uv
                    vertices[index++] = sourceWidth + sourceX;
                    vertices[index++] = sourceHeight + sourceY;
                    // alpha
                    verticesUint32View[index++] = alpha;
                    // xy
                    //GYLite 对无变换的矩阵优化
                    if(noTransform)
                    {
                        vertices[index++] = tx;
                        vertices[index++] = h + ty;
                    }
                    else
                    {
                        vertices[index++] = c * h + tx;
                        vertices[index++] = d * h + ty;   
                    }  
                    // uv
                    vertices[index++] = sourceX;
                    vertices[index++] = sourceHeight + sourceY;
                    // alpha
                    verticesUint32View[index++] = alpha;
                }
                // 缓存索引数组
                // if (this.hasMesh) {
                //     var indicesForMesh = this.indicesForMesh;
                //     indicesForMesh[this.indexIndex + 0] = 0 + this.vertexIndex;
                //     indicesForMesh[this.indexIndex + 1] = 1 + this.vertexIndex;
                //     indicesForMesh[this.indexIndex + 2] = 2 + this.vertexIndex;
                //     indicesForMesh[this.indexIndex + 3] = 0 + this.vertexIndex;
                //     indicesForMesh[this.indexIndex + 4] = 2 + this.vertexIndex;
                //     indicesForMesh[this.indexIndex + 5] = 3 + this.vertexIndex;
                // }
                this.vertexIndex += 4;
                this.indexIndex += 6;
            }
        }
    }
    
}